package com.bear.newsset.widget;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bear.newsset.R;
import com.bear.newsset.util.AnimUtil;
import com.bear.newsset.util.AppUtil;
import com.bear.newsset.util.Utils;
import com.ybear.extranotifybarheightlayout.utils.StatusBarUtils;

import de.hdodenhof.circleimageview.CircleImageView;

/**
 * 一个头像信息View
 *
 * 高度说明：
 *      1.整个View的高度根据子布局的高度为主。
 *      2.为了保证沉浸式能够正常显示，除了头像、底部昵称以外，头像上方增加一个额外View作为高度补偿。
 *      3.额外View的高度为：状态栏高度 + 10dp，这样缩小时头像不会被状态栏挡住，并且还有一定空间。
 *      4.头像、右边昵称被一个父布局包裹，父布局的高度为：头像高度的80% - 状态栏高度。
 *      5.缺点：缩小时的头像大小只会根据父布局设置的高度；预留View很难再次开发。
 *
 * 允许通过 {@link #onScrollListener(float, int)} 监听某个滑动实现头像滑动动画
 */
public class SimpleUserInfoView extends LinearLayout {
    /**
     * 滑动状态监听器  -   上滑/下滑时触发且每次只触发一次
     */
    public interface OnScrollStatusListener {
        void onScrollStatus(View v, boolean isUp);
    }

    private CircleImageView ivUserImg;
    private LinearLayout lChild;
    @DrawableRes
    private int userImg;
    private String userName;
    private int p10, p5, p2, screenWidth, statusBar, childMaxHeight, imgMaxSize;
    private float oldY = -1, totalScrollRange = -1, userNameBottomFixedY = -1;
    private boolean isUp;
    private TextView tvUserNameRight, tvUserNameBottom;

    public OnScrollStatusListener mOnScrollStatusListener;

    public SimpleUserInfoView(Context context) {
        super(context);
        init();
    }

    public SimpleUserInfoView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SimpleUserInfoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        initData();
        setOrientation( VERTICAL );
        setBackgroundResource( R.color.colorWhite );
        setGravity( Gravity.CENTER );
        //允许子View超出范围，所在在嵌套父布局及根布局必须也要设置，否则无法使用
        setClipChildren( false );
        //加载布局
        loadLayout();
        //设置默认用户信息
        setUserInfo(userImg, userName);
    }

    private void initData() {
        //状态栏高度
        statusBar = StatusBarUtils.getStatusBarHeight(getContext());
        //屏幕宽度
        screenWidth = getResources().getDisplayMetrics().widthPixels;
        //头像最大宽度及高度
        imgMaxSize = Utils.dp2Px( getContext(), 100 );
        //包裹头像、右昵称的布局高度
        childMaxHeight = (int) ((0.8F * imgMaxSize - statusBar));

        userImg = R.drawable.ic_def_user_img;
        userName = AppUtil.getAppName(getContext()) + "用户";
        p10 = Utils.dp2Px(getContext(), 10);
        p5 = Utils.dp2Px(getContext(), 5);
        p2 = Utils.dp2Px(getContext(), 2);
    }

    @DrawableRes
    public int getUserImg() { return userImg; }

    public String getUserName() { return userName; }

    public SimpleUserInfoView setUserImg(@DrawableRes int userImg) {
        this.userImg = userImg;
        setUserInfo(userImg, null);
        return this;
    }

    public SimpleUserInfoView setUserName(@NonNull String userName) {
        this.userName = userName;
        setUserInfo(-1, userName);
        return this;
    }

    /**
     * 设置滑动状态监听器  -   上滑/下滑时触发且每次只触发一次
     * @param mOnScrollStatusListener       回调
     */
    public void setOnScrollStatusListener(OnScrollStatusListener mOnScrollStatusListener) {
        this.mOnScrollStatusListener = mOnScrollStatusListener;
    }

    /**
     * 触发滑动监听器
     * 上滑触发条件：scrollY的位置是当前totalScrollRange的 70%
     * 下滑触发条件：scrollY的位置是当前totalScrollRange的 30%
     * @param scrollY               滑动的Y轴
     * @param totalScrollRange      总滑动区间
     */
    public void onScrollListener(float scrollY, int totalScrollRange) {
        float y = Math.abs( scrollY );
        if( oldY == -1 ) oldY = y;
        if( this.totalScrollRange == - 1 ) this.totalScrollRange = totalScrollRange;
        if( userNameBottomFixedY == -1 ) userNameBottomFixedY = tvUserNameBottom.getY();
        //滑动动画
        changeAnimation( y );
        //延迟10millis改变旧的y
        postDelayed(() -> oldY = y, 10);
    }

    /**
     * 滑动动画
     * 头像缩放左右移动、底部昵称上下移隐藏显示、右边昵称隐藏显示
     * @param y     y轴
     */
    private void changeAnimation(float y) {
        /* 向上，缩小 */
        if( !isUp && y + totalScrollRange * 0.7 > totalScrollRange ) {
            //上滑动画
            startUpAnimation();
            //回调监听器
            if( mOnScrollStatusListener != null ) {
                mOnScrollStatusListener.onScrollStatus( this, true );
            }
            isUp = true;
        }
        /* 向下，放大 */
        if( isUp && y - totalScrollRange * 0.3 < 0 ) {
            //下滑动画
            startDownAnimation();
            //回调监听器
            if( mOnScrollStatusListener != null ) {
                mOnScrollStatusListener.onScrollStatus( this, false );
            }
            isUp = false;
        }
    }

    /**
     * 开始上滑动画
     */
    private void startUpAnimation() {
        //底部昵称需要移动的Y值
        float userNameBottomMoveY = userNameBottomFixedY - tvUserNameBottom.getHeight();
        //减少头像外边框的宽度
        ivUserImg.setBorderWidth( p2 );
        //移动位置到最左边
        AnimUtil.startMoveXAnim(lChild, Utils.dp2Px(getContext(), 10));
        //缩小
        AnimUtil.startZoomAnim(ivUserImg, childMaxHeight + p5);
        //显示右边的昵称
        AnimUtil.startAlphaAnim(tvUserNameRight, true);
        //隐藏底部的昵称
        AnimUtil.startAlphaAnim(tvUserNameBottom, false);
        //移动底部昵称到上边，大概自身高度的距离
        AnimUtil.startMoveYAnim(tvUserNameBottom, userNameBottomMoveY);
    }

    /**
     * 开始下滑动画
     */
    private void startDownAnimation() {
        //还原头像外边框的宽度
        ivUserImg.setBorderWidth( p5 );
        //父布局移动位置到中间
        AnimUtil.startMoveXAnim(lChild, screenWidth / 2F - imgMaxSize / 2F);
        //头像放大
        AnimUtil.startZoomAnim(ivUserImg, imgMaxSize);
        //隐藏右边昵称
        AnimUtil.startAlphaAnim(tvUserNameRight, false);
        //显示底部昵称
        AnimUtil.startAlphaAnim(tvUserNameBottom, true);
        //移动底部昵称到下边，大概自身高度的距离
        AnimUtil.startMoveYAnim(tvUserNameBottom, userNameBottomFixedY);
    }

    /**
     * 加载布局
     */
    private void loadLayout() {
        //预留View
        View reservedView = new View(getContext());
        LayoutParams imgLP;
        //包裹头像、右昵称
        lChild = new LinearLayout( getContext() );
        lChild.setLayoutParams( new LayoutParams(LayoutParams.WRAP_CONTENT, childMaxHeight) );
        lChild.setOrientation( HORIZONTAL );
        lChild.setGravity( Gravity.CENTER );

        //添加头像View
        lChild.addView( ( ivUserImg = createUserImgView() ) );
        //添加昵称View
        lChild.addView( ( tvUserNameRight = createUserNameView() ) );
        //添加预留到父布局
        addView( reservedView );
        //添加到父布局
        addView( lChild );
        //添加底昵称View
        addView( ( tvUserNameBottom = createUserNameView() ) );

        //设置预留位宽高，高度大概是状态栏高度 + 额外高度（p5）
        reservedView.setLayoutParams(
                new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBar + Utils.dp2Px(getContext(), 10))
        );

        //设置头像参数
        imgLP = new LayoutParams(imgMaxSize, imgMaxSize);
        imgLP.gravity = Gravity.BOTTOM;
        ivUserImg.setLayoutParams( imgLP );

        //右边昵称左间距
        tvUserNameRight.setPadding(p5, 0, 0, 0);
        //下边昵称上间距
        tvUserNameBottom.setPadding(0, p5, 0, 0);
        //默认隐藏右边的昵称
        tvUserNameRight.setVisibility( GONE );
    }

    /**
     * 创建头像View
     * @return      {@link CircleImageView}
     */
    private CircleImageView createUserImgView() {
        CircleImageView v = new CircleImageView( getContext() );
        v.setImageResource( R.drawable.ic_def_user_img);
        v.setContentDescription("");
        v.setBorderWidth( p5 );
        v.setBorderColor( Color.WHITE );
        return v;
    }

    /**
     * 创建昵称View
     * @return      {@link TextView}
     */
    private TextView createUserNameView() {
        TextView v = new TextView( getContext() );
        v.setText( R.string.default_title );
        v.setTextColor( Color.BLACK );
        v.setTextSize( 20 );
        v.setTypeface(Typeface.DEFAULT_BOLD);
        v.setGravity( Gravity.CENTER );
        return v;
    }

    /**
     * 设置用户信息
     * @param img       头像资源
     * @param name      昵称
     */
    private void setUserInfo(@IntRange(from = -1) @DrawableRes int img, @Nullable String name) {
        if( img != -1 ) ivUserImg.setImageResource( img );
        if( name == null ) return;
        tvUserNameRight.setText( name );
        tvUserNameBottom.setText( name );
    }
}